来源说明:本文档译自 Claude Code 开源代码架构分析,原文为英文技术架构说明,本文进行完整中文解读与结构化重组。
Agent(智能体)的核心是一个循环运行的系统,它不断接收输入、思考、规划、执行,直到任务完成。一个典型的 Agent 架构如下:
用户输入 → 思考 → 规划 → 工具调用 → 执行结果
↓
[继续循环] 或 [输出给用户]
这个循环的精妙之处在于:Agent 不需要预先知道所有步骤,而是通过"思考+执行+反馈"逐步完成任务。
Claude Code 采用了分层架构,从用户界面到 API 调用共有四层:
┌─────────────────────────────────────────────────────────┐
│ REPL.tsx │
│ (用户界面层) │
│ • 捕获用户输入 │
│ • 渲染消息和工具结果 │
│ • 管理键盘快捷键 │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ QueryEngine │
│ (会话管理层) │
│ • 管理多轮对话状态(mutableMessages) │
│ • 处理用户输入(submitMessage) │
│ • 整合系统提示词(fetchSystemPromptParts) │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ query() — 核心循环 │
│ (Async Generator,流式处理) │
│ │
│ while (true) { │
│ [THINK] → 构建请求,调用 API,处理 thinking 块 │
│ [PLAN] → 解析 tool_use,执行工具 │
│ [OUTPUT] → yield 消息事件,检查是否继续 │
│ } │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ services/api/claude.ts │
│ (API 适配层) │
│ • Anthropic SDK / Bedrock / Vertex / Azure │
│ • 流式响应处理 │
└─────────────────────────────────────────────────────────┘
| 层级 | 模块 | 职责 | 生命周期 |
|---|---|---|---|
| 用户界面 | REPL.tsx |
捕获输入,渲染输出 | 长 |
| 会话管理 | QueryEngine |
管理多轮对话状态、权限 | 长 |
| 核心循环 | query() |
处理单个 API 请求/响应,执行工具 | 短(每轮对话可能调用多次) |
| API 适配 | claude.ts |
对接各大 AI 服务商 | 长 |
为什么这样拆分?
- QueryEngine 是"长寿命"的,管理整个会话的生命周期
- query() 是"短寿命"的,每轮对话可能多次调用它来处理复杂任务
传统方式(等所有结果):
用户 → [等待 AI 完全思考完] → [等待所有工具执行完] → 返回结果
↑漫长的等待,用户以为卡死了
流式方式(实时响应):
用户 → yield thinking... → yield "我将执行 ls..."
→ yield 工具结果...
→ yield "完成了!"
↑ 用户实时看到 AI 的思考和行动
Claude Code 使用 JavaScript 的 Async Generator(异步生成器)实现真正的流式响应。query() 不是等所有结果都计算完再返回,而是每产出一个中间结果就 yield 出去,上层界面实时渲染给用户。
这解决了 Agent 应用的一个核心体验问题:用户不知道 AI 在干什么,以为它卡死了。
while (true) {
// THINK → PLAN → TOOL → OUTPUT
const result = yield messageEvent;
if (!result.needsFollowUp) {
return; // 完成,退出循环
}
// 否则继续循环
}
当 AI 认为不需要继续执行工具时,循环结束,结果返回给用户。
┌───────────────────────────────────────┐
│ Tool Registry │
│ tools.ts │
│ │
│ • BashTool / GlobTool / GrepTool │
│ • FileEditTool / AgentTool │
│ • ... 共 30+ 种工具 │
└───────────────────────────────────────┘
│
▼
┌───────────────────────────────────────┐
│ Tool Interface │
│ src/Tool.ts │
│ │
│ name: string │
│ inputSchema: Zod │
│ call(): Promise<ToolResult> │
│ renderResult(): ReactNode │
└───────────────────────────────────────┘
每种工具都有: - name:工具名称 - inputSchema:用 Zod 定义的输入校验 - call():实际执行逻辑 - renderResult():在界面上渲染结果
┌─────────────────────────────────────────────────────┐
│ StreamingToolExecutor │
│ (流式工具执行器) │
│ │
│ 传统方式:所有工具串行执行完再返回 │
│ 流式方式:工具开始就 yield 结果,实时显示给用户 │
└─────────────────────────────────────────────────────┘
StreamingToolExecutor 允许工具边执行边 yield 结果,长时工具(如代码编译、大规模搜索)不会阻塞整个系统。
当对话越来越长,token 数量会逼近上下文窗口上限。Claude Code 的解决方案是自动上下文压缩:
messages[] ────────────────────────────────────────────
│
│ [用户消息1] [助手回复1] [工具结果1] [助手回复2] ...
│
│ │
│ ▼
│ 当上下文过长时...
│ │
│ ▼
│ ┌──────────────────────────────────────────────────┐
│ │ AUTO COMPACT │
│ │ │
│ │ [用户消息1] [助手回复1] [工具结果1] [助手回复2] │
│ │ ↓ │
│ │ [用户消息1] [助手回复1] [ COMPACT_SUMMARY ] │
│ │ └────── 用摘要替换旧消息 ───────┘ │
│ │ │
│ │ 继续对话,但 token 数量减少了 │
│ └──────────────────────────────────────────────────┘
└───────────────────────────────────────────────────────
旧的多轮对话被压缩成一个 COMPACT_SUMMARY 块,保留关键信息的同时大幅减少 token 消耗。这使得超长对话成为可能,用户可以持续和 AI 协作数小时甚至数天。
| 组件 | 标准 Agent | Claude Code |
|---|---|---|
| 输入 | User/Task | submitMessage() |
| 思考 | LLM 推理 | API response(thinking blocks) |
| 规划 | Tool selection | tool_use blocks + runTools() |
| 执行 | Tool execution | StreamingToolExecutor |
| 输出 | Final response | yield 实时流式响应 |
| 记忆 | Memory/History | mutableMessages[] + compact |
| 循环 | While not done | while(true) + continue |
用户输入 "/buddy"
│
▼
REPL.tsx 捕获输入
│
▼
QueryEngine.submitMessage()
│
┌─────┴──────┐
│ │
▼ ▼
fetchSystemPromptParts() processUserInput()
│(构建系统提示词) (处理slash命令)
│
▼
query() AsyncGenerator
│
├─► deps.callModel() ← 调用 AI API(流式)
│ │
│ ├─► yield 'thinking...' (如果有思考块)
│ │
│ ├─► yield 'text_delta...' (实时文本)
│ │
│ └─► yield 'tool_use...' (工具调用请求)
│
├─► streamingToolExecutor ← 流式执行工具
│ │
│ └─► yield tool results (实时工具结果)
│
├─► 检查 needsFollowUp
│ │
│ ├─► true: continue ← 继续循环
│ │
│ └─► false: return ← 完成
│
▼
REPL.tsx 渲染结果
│
▼
用户看到实时响应
可以实时看到 AI 的推理和行动,不会以为它卡死了
分离 QueryEngine 和 query()
QueryEngine 管理会话生命周期(长寿命)query() 处理单轮对话逻辑(短寿命)
流式工具执行
长时工具不会阻塞用户界面
自动上下文压缩
| 模块 | 文件路径 | 职责 |
|---|---|---|
| 入口 | src/entrypoints/cli.tsx |
CLI 入口,命令路由 |
| 主程序 | src/main.tsx |
初始化,REPL 启动 |
| 会话管理 | src/QueryEngine.ts |
多轮对话状态管理 |
| 核心循环 | src/query.ts |
Async Generator 实现 |
| API 层 | src/services/api/claude.ts |
Anthropic API 封装 |
| 工具注册 | src/tools.ts |
工具列表管理 |
| 工具定义 | src/tools/<Name>/ |
各工具实现 |
| 状态管理 | src/state/AppState.tsx |
React 状态 |
| REPL UI | src/screens/REPL.tsx |
交互界面 |
Claude Code 的架构设计体现了几个重要的工程原则:
对于想构建自己 Agent 系统的人来说,Claude Code 的源码是一个非常好的参考样本——它足够简单(不是那种上千人的巨型项目),又足够完整(覆盖了 Agent 的所有核心要素)。
本文档为 Claude Code 开源代码的架构解读,原始分析来自 agent-architecture.md。